package
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.getTimer;
	
	import org.blch.geom.Circle;
	import org.blch.geom.Line2D;
	import org.blch.geom.LineArray;
	import org.blch.geom.Polygon;
	import org.blch.geom.Vector2f;
	import org.blch.util.GeomUtils;
	
	public class CrossBlock extends Sprite
	{
		private var beginlL:Line2D;
		private var circle:Circle;
		private var poly:Polygon;
		private var poly2:Polygon;
		private var lShape:Shape;
		private var baselineShape:Shape;
		private var txt:TextField;
		private var lineV:Vector.<Line2D>;
		
		public function CrossBlock()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			lShape = new Shape;
			this.addChild(lShape);
			baselineShape = new Shape;
			this.addChild(baselineShape);
			init();
			initGETline();
			//initCricle();
			//initCricleIntersection();
		}
		private function init():void{
			txt = new TextField;
			txt.width = 200;
			txt.height = 20;
			this.addChild(txt);
			lineV = new Vector.<Line2D>;
		}
		private function initCricleIntersection():void{
			lShape.graphics.lineStyle(1,0xff0000);
			
			var p1:Vector2f = new Vector2f(100,100);
			var p2:Vector2f = new Vector2f(233,458);
			beginlL = new Line2D(p1,p2);
			
			lShape.graphics.moveTo(p1.x,p1.y);
			lShape.graphics.lineTo(p2.x,p2.y);
			
			circle = new Circle(200,200,100);
			
			lShape.graphics.drawCircle(circle.center.x,circle.center.y,circle.radius);
			
			var point1:Vector2f = new Vector2f();
			var point2:Vector2f = new Vector2f();
			
			GeomUtils.getCricleIntersection(beginlL,circle,point1,point2);
			
			lShape.graphics.lineStyle(0,0x00ff00);
			lShape.graphics.beginFill(0x00ff00,3);
			lShape.graphics.drawCircle(point1.x,point1.y,3);
			lShape.graphics.drawCircle(point2.x,point2.y,3);
			
			
		}
		private function initCricleIntersection2():void{
			lShape.graphics.lineStyle(1,0xff0000);
			
			var p1:Vector2f = new Vector2f(100,100);
			var p2:Vector2f = new Vector2f(233,458);
			beginlL = new Line2D(p1,p2);
			
			lShape.graphics.moveTo(p1.x,p1.y);
			lShape.graphics.lineTo(p2.x,p2.y);
			
			circle = new Circle(200,200,100);
			
			lShape.graphics.drawCircle(circle.center.x,circle.center.y,circle.radius);
			
			//var timer:Number = getTimer();
			
			var k:Number = (p2.y-p1.y)/(p2.x-p1.x);
			var b:Number = p1.y - k*p1.x;
			var c:Number = b - circle.center.y
			
			var A:Number = k*k + 1;
			var B:Number = 2*k*c- 2*circle.center.x;
			var C:Number = c*c + circle.center.x*circle.center.x-circle.radius*circle.radius;
			
			var x1:Number = (-B+Math.sqrt(B*B-4*A*C))/2/A;
			var y1:Number = k*x1+b;
			
			var x2:Number = (-B-Math.sqrt(B*B-4*A*C))/2/A;
			var y2:Number = k*x2+b;
			
			//trace(getTimer()-timer);
			
			lShape.graphics.lineStyle(0,0x00ff00);
			lShape.graphics.beginFill(0x00ff00,3);
			lShape.graphics.drawCircle(x1,y1,3);
			lShape.graphics.drawCircle(x2,y2,3);
			
			
		}
		private function initCricle():void{
			initRandomPoly();
			poly.drawCircle();
			stage.addEventListener(MouseEvent.CLICK,onMouseClick2);
		}
		private function initGETline():void{
			initPoly();
			initLine();
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
			stage.addEventListener(MouseEvent.CLICK,onMouseClick);
		}
		private function initLine():void{
			var p1:Vector2f = new Vector2f(100,100);
			var p2:Vector2f = new Vector2f(233,458);
			beginlL = new Line2D(p1,p2);
			beginlL.drawThis(baselineShape.graphics,0x00ff00);
			if(poly.getRatelition(beginlL)){
				getNEWline(beginlL);
			}
			//lineV.push(beginlL);
			draw();
		}
		
		private function initPoly():void{
			if(poly){
				poly.parent.removeChild(poly);
			}
			var v:Vector.<Vector2f> = new Vector.<Vector2f>;
			v.push(new Vector2f(300,454));
			v.push(new Vector2f(389,406));
			v.push(new Vector2f(430,323));
			v.push(new Vector2f(417,232));
			v.push(new Vector2f(346,172));
			v.push(new Vector2f(235,121));
			v.push(new Vector2f(154,215));
			v.push(new Vector2f(119,331));
			v.push(new Vector2f(194,425));
			poly = new Polygon(v.length,v);
			//traceV(v);
			this.addChildAt(poly,0);
			poly.draw(true);
			
			initRandomPoly2();
		}
		private function traceV(v:Vector.<Vector2f>):void{
			return;
			trace("*********************************************")
			for(var i:int;i<v.length;i++){
				trace("v.push(new Vector2f(" + int(v[i].x) + "," + int(v[i].y)+ "));")
			}
		}
		
		private function initRandomPoly():void{
			if(poly){
				poly.parent.removeChild(poly);
			}
			var v:Vector.<Vector2f> = new Vector.<Vector2f>;
			var begin:int = 180*Math.random();
			var angle:int = begin;
			while(angle < 360+begin){
				var RaAngle:Number = Math.PI*angle/180;
				var r:int = (100+Math.random()*50)
				var x:int = 300 + r*Math.sin(RaAngle);
				var y:int = 300 + r*Math.cos(RaAngle);
				v.push(new Vector2f(x,y));
				angle += 90;
			}
			traceV(v);
			poly = new Polygon(v.length,v);
			this.addChildAt(poly,0);
			poly.draw(true);
		}
		
		private function initRandomPoly2():void{
			if(poly2){
				poly2.parent.removeChild(poly2);
			}
			var v:Vector.<Vector2f> = new Vector.<Vector2f>;
			var angle:int;
			while(angle < 360){
				var RaAngle:Number = Math.PI*angle/180;
				var r:int = (100+Math.random()*50)
				var x:int = 500 + r*Math.sin(RaAngle);
				var y:int = 500 + r*Math.cos(RaAngle);
				v.push(new Vector2f(x,y));
				angle += 90;
			}
			traceV(v);
			poly2 = new Polygon(v.length,v);
			this.addChildAt(poly2,0);
			poly2.draw(true);
		}
		
		private var LRflag:Boolean;
		private function processLines():void{
			
		}
		private var currentAry:Array;
		private function getNEWline(l:Line2D):void{
			var leftary:Array = new Array;
			var rightary:Array = new Array;
			for(var i:int;i<poly.vertexNmu;i++){
				var obj:Object = new Object;
				obj.l = (l.signedDistance(poly.vertexV[i]));
				//trace(obj.l)
				obj.v = poly.vertexV[i];
				if(obj.l > 0 ){
					leftary.push(obj);
				}else{
					obj.l = -obj.l;
					rightary.push(obj);
				}
			}
			
			for(i=0;i<poly2.vertexNmu;i++){
				obj = new Object;
				obj.l = (l.signedDistance(poly2.vertexV[i]));
				obj.v = poly2.vertexV[i];
				if(obj.l > 0 ){
					leftary.push(obj);
				}else{
					obj.l = -obj.l;
					rightary.push(obj);
				}
			}
			
			if(leftary.length == 0 || rightary.length == 0){
				return;
			}
			
			var leftMax:Object = getMaxFromArry(leftary);
			var rightMax:Object = getMaxFromArry(rightary);
						
			lShape.graphics.clear();
			
			if(leftMax.l < rightMax.l){
				var l1:Line2D = new Line2D(l.pointA,leftMax.v);
				var l2:Line2D = new Line2D(leftMax.v,l.pointB);
				//trace(leftMax.v.x + "," + leftMax.v.y);
				
				var la1:LineArray = new LineArray(l1,leftary,LineArray.LEFT);
				var la2:LineArray = new LineArray(l2,leftary,LineArray.LEFT);
				
			}else{
				l1 = new Line2D(l.pointA,rightMax.v);
				l2 = new Line2D(rightMax.v,l.pointB);
				
				la1 = new LineArray(l1,rightary,LineArray.RIGHT);
				la2 = new LineArray(l2,rightary,LineArray.RIGHT);
				//trace(rightMax.v.x + "," + rightMax.v.y);
			}
			iteratLine(la1);
			iteratLine(la2);
			
			/*if(leftary[0].l > rightary[0].l){
				var l1:Line2D = new Line2D(l.pointA,rightary[0].v);
				var l2:Line2D = new Line2D(rightary[0].v,l.pointB);
				trace(rightary[0].v.x + "," + rightary[0].v.y);
			}else{
				l1 = new Line2D(l.pointA,leftary[0].v);
				l2 = new Line2D(leftary[0].v,l.pointB);
				trace(leftary[0].v.x + "," + leftary[0].v.y);
			}*/
			
			
			/*if(poly.getRatelition(l1)){
				getNEWline(l1);
			}else{
				lineV.push(l1);
			}
			
			if(poly.getRatelition(l2)){
				getNEWline(l2);
			}else{
				lineV.push(l2);
			}*/
			
		}
		private function iteratLine(lineAry:LineArray):void{
			var line:Line2D = lineAry.line;
			var ary:Array = lineAry.v;
			var resultAry:Array = new Array;
			for(var i:int;i<ary.length;i++){
				var obj:Object = new Object;
				obj.l = int(line.signedDistance(ary[i].v));
				obj.v = ary[i].v;
				if(lineAry.dircet == LineArray.LEFT){
					if(obj.l > 0 ){
						resultAry.push(obj);
					}
				}else if(lineAry.dircet == LineArray.RIGHT){
					if(obj.l < 0){
						obj.l = -obj.l;
						resultAry.push(obj);
					}
				}
			}
			if(resultAry.length == 0){
				lineV.push(lineAry.line);
				return;
			}
			
			var maxObject:Object = getMaxFromArry(resultAry);
			
			var l1:Line2D = new Line2D(line.pointA,maxObject.v);
			var l2:Line2D = new Line2D(maxObject.v,line.pointB);
			
			var la1:LineArray = new LineArray(l1,resultAry,lineAry.dircet);
			iteratLine(la1);
			var la2:LineArray = new LineArray(l2,resultAry,lineAry.dircet);
			iteratLine(la2);
			
		}
		private function getMaxFromArry(ary:Array):Object{
			var obj:Object;
			if(ary.length>=1){
				obj = ary[0];
			}else{
				return null;
			}
			for(var i:int = 1;i<ary.length;i++){
				if(obj.l < ary[i].l){
					obj = ary[i];
				}
			}
			return obj;	
		}
		private function onMouseMove(event:MouseEvent):void{
			lineV = new Vector.<Line2D>;
			lShape.graphics.clear();
			baselineShape.graphics.clear();
			var p1:Vector2f = new Vector2f(100,100);
			var p2:Vector2f = new Vector2f(event.stageX,event.stageY);
			beginlL = new Line2D(p1,p2);
			beginlL.drawThis(baselineShape.graphics,0x00ff00);
			var timer:int = getTimer();
			if(poly.getRatelition(beginlL)){
				getNEWline(beginlL);
			}
			draw();
			print("x:" + p2.x + ",y:" + p2.y + "    判断时间：" + (getTimer()-timer));
		}
		
		private function onMouseClick(event:MouseEvent):void{
			//initPoly();
			initRandomPoly();
			initRandomPoly2();
		}
		
		private function onMouseClick2(event:MouseEvent):void{
			initRandomPoly();
			//var timer:int = getTimer();
			poly.drawCircle();
			//trace(getTimer()-timer);
		}
		
		private function draw():void{
			for(var i:int;i<lineV.length;i++){
				lineV[i].drawThis(lShape.graphics);
			}
		}
		private function print(str:String):void{
			txt.text = str;
		}
		
	}
}

/*
A=sqrt((Xa-Xb)*(Xa-Xb)+(Ya-Yb)*(Ya-Yb))
B=sqrt((Xa-Xc)*(Xa-Xc)+(Ya-Yc)*(Ya-Yc))
C=sqrt((Xb-Xc)*(Xb-Xc)+(Yb-Yc)*(Yb-Yc))
y=(A+B+C)/2
x=sqrt(y*(y-A)*(y-B)*(y-C))
r=A*B*C/(4*x)
*/
	